﻿using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using WatiN.Core;
using System.Collections.Generic;

namespace FrameworkTest.Helper
{
    /// <summary>
    /// Contiene las funciones para facilitar los Test automatizados sobre el sitio web
    /// </summary>
    public static class SimulatorWeb
    {
        /// <summary>
        /// Escribe el texto sobre un textbox
        /// </summary>
        /// <param name="ie">DOM</param>
        /// <param name="idControl">id del control</param>
        /// <param name="textoAEscribir">Texto a ingresa</param>
        public static void TextoEscribe(IE ie, string idControl, string textoAEscribir)
        {

            var textNullable = ie.TextFields.FirstOrDefault(tb => Equals(tb.Id.Contains(idControl), true));
            if (textNullable == null)
                Assert.Fail(string.Format("No se encuentra el textbox : '{0}'", idControl));
            textNullable.TypeText(textoAEscribir);
        }
        /// <summary>
        /// Valida si nos encontramos en la pagina especificada
        /// </summary>
        /// <param name="ie">DOM</param>
        /// <param name="url">Url de la pagina que se quiere validar</param>
        public static void ValidaPagina(IE ie, string url)
        {
            Assert.IsTrue(ie.Url.Contains(url), string.Format("La pagina {0} no existe", url));
        }
        /// <summary>
        /// Valida la existencia del boton
        /// </summary>
        /// <param name="ie">DOM</param>
        /// <param name="texto">Texto del boton en cuestion</param>
        public static Button Button(IE ie, string texto)
        {
            var botonNullable = ie.Buttons.FirstOrDefault(btn => btn.Text.Contains(texto));
            if (botonNullable == null)
                Assert.Fail(string.Format("El boton con el texto '{0}' no existe", texto));
            return botonNullable;
        }
        /// <summary>
        /// Valida el dropdownlist y si es modificable (enabled or disabled)
        /// </summary>
        /// <param name="ie">DOM</param>
        /// <param name="idControl">ID del control</param>
        /// <param name="modificable">Indica si es enabled or disabled</param>
        public static SelectList SelectList(IE ie, string idControl, bool modificable)
        {
            var dropDownListNullable = ie.SelectLists.FirstOrDefault(ddl => ddl.Id.Contains(idControl));
            if (dropDownListNullable == null)
                Assert.Fail(string.Format("El dropdownlist con el ID de '{0}' no existe", idControl));
            if (!modificable)
                Assert.IsTrue(dropDownListNullable.GetAttributeValue("disabled") == "True",
                   string.Format("El dropdowlist con el ID '{0}' esta disponible para la modificacion", idControl));
            return dropDownListNullable;
        }
        /// <summary>
        /// Valida el dropdownlist
        /// </summary>
        /// <param name="ie">DOM</param>
        /// <param name="idControl">ID del control</param>
        public static SelectList SelectList(IE ie, string idControl)
        {
            return SelectList(ie, idControl, true);
        }
        /// <summary>
        /// Valida el texto en la pagina web
        /// </summary>
        /// <param name="ie">DOM</param>
        /// <param name="idControl">ID del control</param>
        /// <param name="editable">El valor Value del control puede ser modificado por el usuario</param>
        public static TextField TextBox(IE ie, string idControl, bool editable)
        {
            var textoNullable = ie.TextFields.FirstOrDefault(btn => btn.Id.Contains(idControl));
            if (textoNullable == null)
                Assert.Fail(string.Format("El texto : '{0}' no existe", idControl));
            if (!editable)
                Assert.IsTrue(textoNullable.GetAttributeValue("disabled") == "True",
                    string.Format("El textbox con el ID '{0}' esta disponible para la modificacion", idControl));
            return textoNullable;
        }
        /// <summary>
        /// Valida la lista
        /// </summary>
        /// <param name="ie">DOM</param>
        /// <param name="idControl">ID del control</param>
        /// <param name="item">Elemento de la lista</param>
        /// <param name="modificable">Enabled o Disabled</param>
        public static SelectList SelectList(IE ie, string idControl, string item, bool modificable)
        {
            var selectListNullable = ie.SelectLists.FirstOrDefault(btn => btn.Text.Contains(item));
            if (selectListNullable == null)
                Assert.Fail(string.Format("La SelectList : '{0}' no existe", idControl));

            if (!modificable)
                Assert.IsTrue(selectListNullable.GetAttributeValue("disabled").Equals("disabled"), string.Format("La selectlist con el  ID : '{0}' esta disponible para la modificacion", item));
            return selectListNullable;
        }
        /// <summary>
        /// Valida la lista
        /// </summary>
        /// <param name="ie">DOM</param>
        /// <param name="idControl">ID del control</param>
        /// <param name="item">Elemento de la lista</param>
        public static SelectList SelectList(IE ie, string idControl, string item)
        {
            return SelectList(ie, idControl, item, true);
        }
        /// <summary>
        /// Login en el sistema
        /// </summary>
        /// <param name="ie">DOM</param>
        /// <param name="user">Usuario</param>
        /// <param name="password">Password</param>
        public static void Login(IE ie, string user, string password)
        {
            ie.GoTo("http://localhost/Biblioteca/Login.aspx");
            TextBox(ie, "txtUsuario").TypeText(user);
            TextBox(ie, "txtPassword").TypeText(password);
            Button(ie, "Ingresar").Click();
        }
        /// <summary>
        /// Login en el sistema como usuario
        /// </summary>
        /// <param name="ie">DOM</param>
        public static void LoginUsuario(IE ie)
        {
            Login(ie, "gabo", "gabo");
        }
        /// <summary>
        /// Login en el sistema como administrador
        /// </summary>
        /// <param name="ie">DOM</param>
        public static void LoginAdmin(IE ie)
        {
            Login(ie, "admin", "root");
        }
        /// <summary>
        /// Valida el textbox
        /// </summary>
        /// <param name="ie">DOM</param>
        /// <param name="idTextBox">id del control</param>
        public static TextField TextBox(IE ie, string idTextBox)
        {
            return TextBox(ie, idTextBox, true);
        }
        /// <summary>
        /// Valida un Span
        /// </summary>
        /// <param name="ie">DOM</param>
        /// <param name="idLabel">Id de Span</param>
        public static Span Span(IE ie, string idLabel)
        {
            var spanNullable = ie.Spans.FirstOrDefault(c => c.Id.Contains(idLabel));
            if (spanNullable == null)
                Assert.Fail(string.Format("No se encuentra la etiqueta con el id '{0}'", idLabel));
            return spanNullable;
        }
        /// <summary>
        /// Valida radiobutton
        /// </summary>
        /// <param name="ie">DOM</param>
        /// <param name="idRadioButton">id del radiobutton</param>
        public static RadioButton RadioButton(IE ie, string idRadioButton)
        {
            var radioButonNullable = ie.RadioButtons.FirstOrDefault(c => c.Id.Contains(idRadioButton));
            if (radioButonNullable == null)
                Assert.Fail(string.Format("El radiobuton : '{0}' no existe", idRadioButton));
            return radioButonNullable;
        }
        /// <summary>
        /// Valida radiobutton
        /// </summary>
        /// <param name="ie">DOM</param>
        /// <param name="idRadioButton">id del radiobutton</param>
        /// <param name="list">Colleccion a comparar</param>
        public static RadioButton RadioButton(IE ie, string idRadioButton, List<string> list)
        {
            var radiobuton = RadioButton(ie, idRadioButton);

            //Verificamos que el contenido del radio bouton es el mismo
            var collecionRadioboutons = (from rb in ie.RadioButtons
                                         where rb.GetAttributeValue("name").Contains(idRadioButton) == true
                                         select rb.GetAttributeValue("value")).ToList();

            CollectionAssert.AreEqual(list, collecionRadioboutons, "La colleccion no contiene los mismos items en el radiobutonlist");
            return radiobuton;
        }
        /// <summary>
        /// Valida el select list
        /// </summary>
        /// <param name="ie">DOM</param>
        /// <param name="idControl">id del select list</param>
        /// <param name="collecion">collection a comparar</param>
        public static SelectList SelectList(IE ie, string idControl, List<string> collecion)
        {
            var dropdowList = SelectList(ie, idControl, true);
            CollectionAssert.AreEqual(collecion, ie.SelectLists.First(sl => sl.Id.Contains(idControl) == true).AllContents, "El contenido de la lista no es igual");
            return dropdowList;
        }
        /// <summary>
        /// Valida texto en la DOM
        /// </summary>
        /// <param name="ie">DOM</param>
        /// <param name="texto">Texto a buscar</param>
        public static void ValidaTexto(IE ie, string texto)
        {
            Assert.IsTrue(ie.ContainsText(texto), string.Format("El texto '{0}' no se encuentra en la pagina", texto));
        }
        /// <summary>
        /// Valida el Link
        /// </summary>
        /// <param name="ie">DOM</param>
        /// <param name="text">Texto del link</param>
        public static Link Link(IE ie, string text)
        {
            var linkNullable = ie.Links.FirstOrDefault(c => c.Text.Contains(text));
            if (linkNullable == null)
                Assert.Fail(string.Format("El link : '{0}' no existe", text));
            return linkNullable;
        }
        /// <summary>
        /// Valida el contenido de un span
        /// </summary>
        /// <param name="ie">DOM</param>
        /// <param name="id">id del control</param>
        /// <param name="texto">Texto a valider</param>
        public static void Span(IE ie, string id, string texto)
        {
            var span = Span(ie, id);
            Assert.AreEqual(texto, span.Text, string.Format("El span '{0}', no tiene el texto '{1}', el texto que muestra es '{2}'", id, texto, span.Text));
        }
        /// <summary>
        /// Valida radiobutton
        /// </summary>
        /// <param name="ie">DOM</param>
        /// <param name="idRadioButton">id del radiobutton</param>
        /// <param name="itemSeleccionado">Item seleccionado por defecto</param>
        public static void RadioButton(IE ie, string idRadioButton, string itemSeleccionado)
        {
            var rb = RadioButton(ie, idRadioButton);
            Assert.AreEqual(true, (rb.GetAttributeValue("name").Contains(idRadioButton) == true
        && rb.GetAttributeValue("value") == itemSeleccionado) && rb.Checked, string.Format("'{0}' no esta seleccionado por defecto", itemSeleccionado));
        }
    }
}
